package com.zhou.base.resilience4j.test.util;

import com.zhou.base.resilience4j.test.entity.SystemLog;
import com.zhou.base.resilience4j.test.service.ISystemLogService;
import io.github.resilience4j.bulkhead.BulkheadFullException;
import io.github.resilience4j.bulkhead.annotation.Bulkhead;
import io.github.resilience4j.circuitbreaker.CallNotPermittedException;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
import io.github.resilience4j.retry.annotation.Retry;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeoutException;

@Slf4j
@Component
public class RemoteServiceConnector {

    @Autowired
    private ISystemLogService remoteService;

    @Autowired
    private CircuitBreakerRegistry circuitBreakerRegistry;


    public List<SystemLog> process() throws TimeoutException, InterruptedException {
        List<SystemLog> systemLogs = remoteService.queryAll();
        return systemLogs;
    }

    public List<SystemLog> process1() throws TimeoutException, InterruptedException {
        List<SystemLog> systemLogs = remoteService.queryAllTestTimeLimiter();
        return systemLogs;
    }

    @CircuitBreaker(name = "backendA", fallbackMethod = "fallBack")
    public List<SystemLog> processNew() {
        List<SystemLog> systemLogs = remoteService.queryAll();
        return systemLogs;
    }

    private List<SystemLog> fallBack(Throwable throwable) {
        log.info(throwable.getLocalizedMessage() + ",方法被降级了~~");
        CircuitBreakerUtil.getCircuitBreakerStatus("降级方法中:", circuitBreakerRegistry.circuitBreaker("backendA"));
        List<SystemLog> users = new ArrayList();
        return users;
    }

    private List<SystemLog> fallBack(CallNotPermittedException e) {
        log.info("熔断器已经打开，拒绝访问被保护方法~");
        CircuitBreakerUtil.getCircuitBreakerStatus("熔断器打开中:", circuitBreakerRegistry.circuitBreaker("backendA"));
        List<SystemLog> users = new ArrayList();
        return users;
    }

    @CircuitBreaker(name = "backendA", fallbackMethod = "fallBack")
    @Retry(name = "backendA", fallbackMethod = "fallBack")
    public List<SystemLog> process2() throws TimeoutException, InterruptedException {
        List<SystemLog> users = remoteService.queryAll();
        return users;
    }

    @RateLimiter(name = "backendA", fallbackMethod = "fallBack")
    public List<SystemLog> processRateLimite() throws TimeoutException, InterruptedException {
        List<SystemLog> users = remoteService.queryAllWithRateLimiter();
        return users;
    }

    @Bulkhead(name = "backendA", fallbackMethod = "fallBack", type = Bulkhead.Type.SEMAPHORE)
    public List<SystemLog> processBulkhead() throws TimeoutException, InterruptedException {
        List<SystemLog> systemLogs = remoteService.processWithBulkhead();
        return systemLogs;
    }

    public List<SystemLog> processBulkhead2() throws TimeoutException, InterruptedException {
        List<SystemLog> systemLogs = remoteService.processWithBulkhead();
        return systemLogs;
    }

    @Retry(name = "backendA", fallbackMethod = "fallBack")
    public List<SystemLog> processRetry() throws TimeoutException, InterruptedException {
        List<SystemLog> systemLogs = remoteService.processWithRetry();
        return systemLogs;
    }

    public List<SystemLog> processRetry2() throws TimeoutException, InterruptedException {
        List<SystemLog> systemLogs = remoteService.processWithRetry();
        return systemLogs;
    }


    private List<SystemLog> fallBack(BulkheadFullException e) {
        log.info("服务失败: " + e.getLocalizedMessage());
        return new ArrayList();
    }


}
